﻿using CCL.SocketMessage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CCL.Utility;

namespace CCL.TableStructure
{
    /// <summary>
    /// 직렬화 가능한 Database의 Project Table을 제공합니다.
    /// </summary>
    public class Project : Table, ISerializable
    {
        /// <summary>
        /// 해당 Project의 고유한 ID값을 가져옵니다.
        /// </summary>
        public int ProjectID { get; private set; }

        /// <summary>
        /// 해당 Project의 이름을 가져옵니다.
        /// </summary>
        public char[] ProjectName { get; private set; }

        /// <summary>
        /// 해당 Project의 최상위 버전 Number를 가져옵니다.
        /// </summary>
        public int HeadRevision { get; private set; }

        /// <summary>
        /// 해당 Project의 Owner정보를 가져옵니다.
        /// </summary>
        public User ProjectOwner { get; private set; }
        //public int ProjectOwnerID { get; private set; }

        /// <summary>
        /// 해당 Table의 총 Size
        /// </summary>
        public new const int TableSize =
                sizeof(int) +                   // ProjectID
                Constant.Length.ProjectName +   // ProjectName
                sizeof(int) +                   // HeadRevision
                //sizeof(int);                    // ProjectOwnerID
                User.TableSize;                 // ProjectOwner

        /// <summary>
        /// 새로운 Project Table 객체를 생성합니다.
        /// </summary>
        /// <param name="bytes">직렬화된 byte 배열</param>
        public Project(byte[] bytes)
        {
            int start = 0;

            ProjectID = BitConverter.ToInt32(bytes, start);
            start += sizeof(int);

            ProjectName = new char[Constant.Length.ProjectName];
            Encoding.Default.GetChars(bytes, start, Constant.Length.ProjectName, ProjectName, 0);
            start += Constant.Length.ProjectName;

            HeadRevision = BitConverter.ToInt32(bytes, start);
            start += sizeof(int);

            /*ProjectOwnerID = BitConverter.ToInt32(bytes, start);
            start += sizeof(int);            */

            byte[] userBytes = new byte[bytes.Length - start];
            Array.Copy(bytes, start, userBytes, 0, bytes.Length - start);
            ProjectOwner = new User(userBytes);
        }

        /// <summary>
        /// 새로운 Project Table 객체를 생성합니다.
        /// </summary>
        /// <param name="projId">Project ID</param>
        /// <param name="name">Project 이름</param>
        /// <param name="headRev">최상위 Revision 버전 Number</param>
        /// <param name="user">Owner의 정보</param>
        public Project(int projId, string name, int headRev, User user)
        {
            ProjectID = projId;
            ProjectName = StringUtility.StringCopy(name, Constant.Length.ProjectName);
            HeadRevision = headRev;
            ProjectOwner = user;
        }

        /// <summary>
        /// 바이트 배열로 직렬화 합니다.
        /// </summary>
        /// <returns>직렬화된 바이트 배열</returns>
        public byte[] GetByte()
        {
            byte[] bytes = new byte[GetSize()];

            int destIndex = 0;
            byte[] temp;

            temp = BitConverter.GetBytes(ProjectID);
            Array.Copy(temp, 0, bytes, destIndex, temp.Length);
            destIndex += temp.Length;

            temp = Encoding.Default.GetBytes(ProjectName);
            Array.Copy(temp, 0, bytes, destIndex, Constant.Length.ProjectName);
            destIndex += Constant.Length.ProjectName;

            temp = BitConverter.GetBytes(HeadRevision);
            Array.Copy(temp, 0, bytes, destIndex, temp.Length);
            destIndex += temp.Length;

            temp = ProjectOwner.GetByte();
            Array.Copy(temp, 0, bytes, destIndex, temp.Length);

            return bytes;
        }

        /// <summary>
        /// 직렬화 가능한 객체의 바이트 사이즈를 가져옵니다.
        /// </summary>
        /// <returns>직렬화된 바이트 사이즈</returns>
        public uint GetSize()
        {
            return TableSize;
        }
    }
}
